package com.lovely3x.jobservice.executors.extensions.version.executor;

import android.support.annotation.NonNull;

import com.lovely3x.common.versioncontroller.ApplicationUtils;
import com.lovely3x.common.versioncontroller.Version;
import com.lovely3x.jobservice.executors.TaskExecutor;
import com.lovely3x.jobservice.executors.extensions.version.VersionCheckTask;
import com.lovely3x.jobservice.executors.extensions.version.factory.VersionCheckFactory;
import com.lovely3x.jobservice.serializer.TaskSerializer;
import com.lovely3x.jobservice.task.Progress;
import com.lovely3x.jobservice.task.Task;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 版本检查执行器
 * Created by lovely3x on 16-2-18.
 */
public class VersionCheckExecutor extends TaskExecutor.AbstractTaskExecutor {

    /**
     * 正在检查新版本
     */
    public static final int VERSION_CHECK_RESULT_CHECKING = 1;
    /**
     * 已经是最新版本
     */
    public static final int VERSION_CHECK_RESULT_ALREADY_LATEST = 2;
    /**
     * 发现新版本
     */
    public static final int VERSION_CHECK_RESULT_FOUND_NEW_VERSION = 3;
    /**
     * 发现新版本需要强制更新
     */
    public static final int VERSION_CHECK_RESULT_FOUND_NEW_VERSION_FORCE_UPDATE = 4;
    /**
     * 检查失败
     */
    public static final int VERSION_CHECK_RESULT_FAILURE = 5;

    private final VersionCheckProgress PROGRESS = new VersionCheckProgress();
    private Call mCall;

    @Override
    public Exception execute(Task task) {
        try {
            if (!(task instanceof VersionCheckTask)) throw new UnsupportedOperationException();
            synchronized (PROGRESS) {
                PROGRESS.setCurrent(0);
                PROGRESS.setTask(task.getWhat());
                PROGRESS.setWhen(System.currentTimeMillis());
                PROGRESS.setState(Progress.State.EXECUTING);
            }

            OkHttpClient ohc = new OkHttpClient();
            Request request = new Request.Builder().get().url(((VersionCheckTask) task).getVersionCheckUrl()).build();
            mCall = ohc.newCall(request);
            Response response = mCall.execute();
            if (response.isSuccessful()) {
                Version remoteVersion = ApplicationUtils.parseVersion(response.body().byteStream());
                Version locVersion = ApplicationUtils.getCurrentPackageVersion(mJobService);
                synchronized (PROGRESS) {
                    PROGRESS.setRemoteVersion(remoteVersion);
                    PROGRESS.setLocVersion(locVersion);
                    if (remoteVersion != null && locVersion != null) {
                        //远程的版本号大于本地的版本号
                        if (remoteVersion.getVersionCode() > locVersion.getVersionCode()) {
                            PROGRESS.setCurrent(locVersion.isForceUpdate() ? VERSION_CHECK_RESULT_FOUND_NEW_VERSION_FORCE_UPDATE : VERSION_CHECK_RESULT_FOUND_NEW_VERSION);
                        } else {
                            PROGRESS.setCurrent(VERSION_CHECK_RESULT_ALREADY_LATEST);
                        }
                        PROGRESS.setState(Progress.State.SUCCESSFUL);
                    } else {
                        PROGRESS.setCurrent(VERSION_CHECK_RESULT_FAILURE);
                        PROGRESS.setState(Progress.State.FAILURE);
                    }
                }
            } else {
                throw new RuntimeException(response.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
            synchronized (PROGRESS) {
                PROGRESS.setCurrent(VERSION_CHECK_RESULT_FAILURE);
                PROGRESS.setState(Progress.State.FAILURE);
            }
            return e;
        }
        return null;
    }

    @Override
    public boolean remove() {
        if (mCall != null && !mCall.isCanceled()) {
            try {
                mCall.cancel();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }

    @Override
    public Exception stop() {
        return null;
    }

    @Override
    public Exception resume(Task task, Progress progress) {
        return new UnsupportedOperationException();
    }

    @Override
    public boolean handleable(Task task) {
        return task != null && VersionCheckFactory.EXECUTOR_TYPE.equals(task.getTaskType());
    }

    @NonNull
    @Override
    public Progress getProgress() {
        return PROGRESS;
    }

    @Override
    public void serialize(TaskSerializer serializer) {

    }
}
